package com.ch.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ch.web.ResponseDto.xyDz.XyUserEntityDzTalkRes;
import com.ch.web.config.websocket.WebSocketService;
import com.ch.web.entity.user.XyUserEntity;
import com.ch.web.enums.UserEnumCollection;
import com.ch.web.mapper.XyUserDao;
import com.ch.web.redis.UserMapCache;
import com.ch.web.requestDto.xyUser.UserLoginFormDto;
import com.ch.web.service.XyDzService;
import com.ch.web.service.XyTokenService;
import com.ch.web.service.XyUserService;
import com.ch.web.utils.PageUtils;
import com.ch.web.utils.Query;
import com.ch.web.utils.R;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("xyUserService")
public class XyUserServiceImpl extends ServiceImpl<XyUserDao, XyUserEntity> implements XyUserService {

    @Resource
    XyUserDao xyUserDao;
    @Resource
    XyTokenService xyTokenService;
    @Resource
    XyDzService xyDzService;

    @Resource
    UserMapCache userMapCache;
    @Resource
    WebSocketService webSocketService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<XyUserEntity> queryWrapper = new QueryWrapper<>();
        String userNick = (String) params.get("userNick");
        if (StringUtils.isNotBlank(userNick)) {
            queryWrapper.eq("user_nick", userNick);
        }
        IPage<XyUserEntity> page = this.page(
                new Query<XyUserEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public R checkLogin(UserLoginFormDto dto) throws Exception {
        String username = dto.getUsername();
        QueryWrapper<XyUserEntity> eq = new QueryWrapper<XyUserEntity>().eq("user_password", dto.getPassword());
        eq.and(cou -> {
            cou.eq("user_name", username).or().eq("user_tel", username).or().eq("user_email", username);
        });
        XyUserEntity xyUserEntity = this.getBaseMapper().selectOne(eq);
        if (ObjectUtils.isEmpty(xyUserEntity)) {
            return R.error(UserEnumCollection.USER_NOT_FOUND.getCode(), UserEnumCollection.USER_NOT_FOUND.getMessage());
        }
        //表示登录成功
        //进行逻辑判断
        if (xyUserEntity.getUserStatus() == 0) {
            return R.error(UserEnumCollection.USER_IS_BLANK.getCode(), UserEnumCollection.USER_IS_BLANK.getMessage());
        } else if (xyUserEntity.getUserStatus() == 2) {
            return R.error(UserEnumCollection.USER_WF_BLANK.getCode(), UserEnumCollection.USER_WF_BLANK.getMessage() + xyUserEntity.getUserWfTime());
        } else {
            //表示正常状态 创建token
            return xyTokenService.createToken(xyUserEntity);
        }
    }

    @Override
    public R checkExistsUserName(String username) {
        QueryWrapper<XyUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", username);
        XyUserEntity entity = this.getOne(wrapper);
        if (ObjectUtils.isEmpty(entity)) {
            return R.ok();
        } else {
            return R.error();
        }
    }

    /**
     * 当这个账号下线的时候 修改状态
     *
     * @param userName
     */
    @Override
    public void logout(String userName) {
        System.out.println(userName + "下线了");
        UpdateWrapper<XyUserEntity> objectUpdateWrapper = new UpdateWrapper<>();
        objectUpdateWrapper.eq("user_name", userName).set("user_online", 0);
        this.update(objectUpdateWrapper);
    }

    @Override
    public List<XyUserEntityDzTalkRes> getDZPersons(Long talkId) {
        List<Long> idList = xyDzService.getDzUserIds(talkId);
        List<XyUserEntityDzTalkRes> collect = idList.parallelStream().map(id -> xyUserDao.getDzUserById(id)).collect(Collectors.toList());
        collect.forEach(System.out::println);
        return collect;
    }

    @Override
    public Long geUserIdByUserNick(String userNick) {
        XyUserEntity xyUserEntity = this.getOne(new QueryWrapper<XyUserEntity>().eq("user_nick", userNick));
        return ObjectUtils.isEmpty(xyUserEntity) ? null : xyUserEntity.getUserId();
    }

    @Override
    public String getAvaByName(String username) {
        XyUserEntity entity = this.getOne(new QueryWrapper<XyUserEntity>().eq("user_name", username));
        if (ObjectUtils.isEmpty(entity)) {
            return "";
        }
        return entity.getUserAva();
    }

    @Override
    public boolean editUserInfo(XyUserEntity xyUserEntity, HttpServletRequest request) {
        Long userId = xyUserEntity.getUserId();
        XyUserEntity entity = this.getById(userId);
        if (ObjectUtils.isEmpty(entity)) {
            return false;
        }
        forceUserDownCheck(xyUserEntity);
        xyUserEntity.setUserStatus(xyUserEntity.getUserStatus());
        return this.updateById(xyUserEntity);
    }

    @Override
    public boolean checkPassword(String oldPassword, HttpServletRequest request) {
        XyUserEntity entity = getUserById(request);
        forceUserDownCheck(entity);
        String userPassword = entity.getUserPassword();
        return userPassword.equals(oldPassword);
    }

    @Override
    public void updatePassword(String newPassword, HttpServletRequest request) {
        XyUserEntity entity = getUserById(request);
        forceUserDownCheck(entity);
        entity.setUserPassword(newPassword);
        this.updateById(entity);
        webSocketService.forceDownByUpdatePassword();
    }

    /**
     * 根据request的token获取用户信息
     *
     * @param request
     * @return
     */
    private XyUserEntity getUserById(HttpServletRequest request) {
        Long userIdByToken = userMapCache.getUserIdByToken(request);
        return this.getById(userIdByToken);
    }

    /**
     * @param entity
     */
    private void forceUserDownCheck(XyUserEntity entity) {
        if (entity.getUserStatus() == 0 || entity.getUserStatus() == 2) {
            webSocketService.forceDown(entity.getUserName());
        }
    }
}
